#ifndef __PACKET_H__
#define __PACKET_H__

#include <stdint.h>
#include "maze.h"

/** Main Packet **/

typedef struct {
	uint16_t sender;
	uint16_t msgType;
	int gameState;
	int bodyLength;
} CtfHeader;

//const short CTF_HEADER_LENGTH = 12;
#define CTF_HEADER_LENGTH 12

typedef struct {
	CtfHeader header;
	char *body;
} CtfPacket;

/** Map Body **/

typedef struct {
	uint16_t rows;
	uint16_t cols;
	uint16_t numHome1;
	uint16_t numHome2;
	uint16_t numJail1;
	uint16_t numJail2;
} MapHeader;

//const short MAP_HEADER_LENGTH = 12;
#define MAP_HEADER_LENGTH 12

typedef struct {
	MapHeader header;
	char *map;
} MapPacket;

/** Response Body **/
typedef struct {
	uint16_t playerId;
} ConnectBody;

//const short CONNECT_BODY_LENGTH = 2;
#define CONNECT_BODY_LENGTH 2

typedef struct {
	Position pos;
} MoveBody;

//const short MOVE_BODY_LENGTH = 4;
#define MOVE_BODY_LENGTH 4

typedef struct {
	uint16_t objectId;
} PickupBody;

//const short PICKUP_BODY_LENGTH = 2;
#define PICKUP_BODY_LENGTH 2

typedef struct {
	uint16_t objectId;
	Position pos;
} DropBody;

//const short DROP_BODY_LENGTH = 6;
#define DROP_BODY_LENGTH 6

typedef struct {
	Position pos;
} BlastBody;

//const short BLAST_BODY_LENGTH = 4;
#define BLAST_BODY_LENGTH 4

typedef struct {
	uint16_t result;
} DisconnectBody;

//const short DISCONNECT_BODY_LENGTH = 2;
#define DISCONNECT_BODY_LENGTH 2

/** Cell + Player Position Update **/
typedef struct {
	uint64_t numCellUpdates;
} CellUpdateHeader;

//const short CELL_UPDATE_HEADER_LENGTH = 4;
#define CELL_UPDATE_HEADER_LENGTH 4

typedef struct {
	Position pos;
	uint16_t cellType;
	uint16_t occupiedByPlayer;
	uint16_t occupiedByObject;
} CellUpdateBody;

//const short CELL_UPDATE_BODY_LENGTH = 10;
#define CELL_UPDATE_BODY_LENGTH 10

typedef struct {
	CellUpdateHeader header;
	CellUpdateBody *updates;
} CellUpdatePacket;


/** Player Update **/
typedef struct {
	uint16_t numPlayerUpdates;
} PlayerUpdateHeader;

//const short PLAYER_UPDATE_HEADER_LENGTH = 2;
#define PLAYER_UPDATE_HEADER_LENGTH 2

typedef struct {
	uint16_t playerId;
	uint16_t field;
	uint16_t value;
} PlayerUpdateBody;

//const short PLAYER_UPDATE_BODY_LENGTH = 6;
#define PLAYER_UPDATE_BODY_LENGTH 6

typedef struct {
	PlayerUpdateHeader header;
	PlayerUpdateBody *updates;
} PlayerUpdatePacket;


/** Game Update **/
typedef struct {
	uint16_t gameState;
} GameUpdateBody;

//const short GAME_UPDATE_BODY_LENGTH = 2;
#define GAME_UPDATE_BODY_LENGTH 2

#endif
